import 'package:flutter/material.dart';

///
/// 单选组
///
class DDRadioGroup<T> extends StatefulWidget {
  final List<DDRadioItemValue<T>> radioItems;
  final T groupValue;
  final double radioSize;
  final Function callback;

  DDRadioGroup(
    this.groupValue,
    this.radioItems, {
    this.radioSize = 80.0,
    this.callback,
  });

  @override
  _DDRadioGroupState createState() => _DDRadioGroupState();
}

class _DDRadioGroupState<T> extends State<DDRadioGroup<T>> {
  DDRadioItemValue<T> _groupValue;

  @override
  void initState() {
    super.initState();
    if (widget.radioItems != null && widget.radioItems.isNotEmpty) {
      for (DDRadioItemValue<T> item in widget.radioItems) {
        if (item.value == widget.groupValue) {
          _groupValue = item;
          break;
        }
      }
    }
  }

  void _onChanged(DDRadioItemValue<T> item) {
    setState(() {
      _groupValue = item;
      if (widget.callback != null) {
        widget.callback(item.value);
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    List<Widget> items = <Widget>[];
    for (DDRadioItemValue<T> item in widget.radioItems) {
      items.add(
        SizedBox(
          width: widget.radioSize,
          child: DDRadioItem<T>(item, _groupValue, _onChanged),
        ),
      );
    }

    return Container(
      padding: EdgeInsets.symmetric(vertical: 5.0),
      child: Row(
        children: items,
      ),
    );
  }
}

///
/// 单选项
///
class DDRadioItem<T> extends StatelessWidget {
  final DDRadioItemValue<T> value;
  final DDRadioItemValue<T> groupValue;
  final ValueChanged<DDRadioItemValue<T>> onChanged;

  DDRadioItem(this.value, this.groupValue, this.onChanged);

  @override
  Widget build(BuildContext context) {
    final ThemeData theme = Theme.of(context);
    return new Container(
      height: 36.0,
      padding: EdgeInsets.all(0.0),
      alignment: AlignmentDirectional.centerStart,
      child: new MergeSemantics(
        child: new Row(children: <Widget>[
          new Radio<DDRadioItemValue<T>>(
            value: value,
            groupValue: groupValue,
            onChanged: onChanged,
          ),
          new Expanded(
            child: new Semantics(
              container: true,
              button: true,
              label: value.text,
              child: new GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: () {
                  onChanged(value);
                },
                child: new Text(
                  value.text,
                  style: theme.textTheme.subhead,
                ),
              ),
            ),
          ),
        ]),
      ),
    );
  }
}

///
/// 单选项值
///
class DDRadioItemValue<T> {
  const DDRadioItemValue({this.text, this.value});

  final String text;
  final T value;

  @override
  String toString() => '$runtimeType("$text", "$value")';
}
